using UnityEngine;

namespace NodeCanvas
{
	[AddComponentMenu("")]
	public class Connection : MonoBehaviour
	{
		[SerializeField]
		private Node _sourceNode;

		[SerializeField]
		private Node _targetNode;

		[SerializeField]
		private bool _isDisabled;

		private Status _connectionStatus = Status.Resting;

		public Node sourceNode
		{
			get
			{
				return _sourceNode;
			}
			private set
			{
				_sourceNode = value;
			}
		}

		public Node targetNode
		{
			get
			{
				return _targetNode;
			}
			private set
			{
				_targetNode = value;
			}
		}

		public Status connectionStatus
		{
			get
			{
				return _connectionStatus;
			}
			set
			{
				_connectionStatus = value;
			}
		}

		public bool isActive
		{
			get
			{
				return !_isDisabled;
			}
			set
			{
				if (!_isDisabled && !value)
				{
					ResetConnection();
				}
				_isDisabled = !value;
			}
		}

		protected Graph graph
		{
			get
			{
				return sourceNode.graph;
			}
		}

		protected Component graphAgent
		{
			get
			{
				return (!(graph != null)) ? null : graph.agent;
			}
		}

		protected Blackboard graphBlackboard
		{
			get
			{
				return (!(graph != null)) ? null : graph.blackboard;
			}
		}

		public static Connection Create(Node source, Node target, int sourceIndex)
		{
			Connection connection = new GameObject(source.ID + "_" + target.ID + "_Connection").AddComponent(source.outConnectionType) as Connection;
			connection.transform.parent = source.transform;
			connection.transform.localPosition = Vector3.zero;
			connection.sourceNode = source;
			connection.targetNode = target;
			connection.sourceNode.outConnections.Insert(sourceIndex, connection);
			connection.targetNode.inConnections.Add(connection);
			connection.OnCreate(sourceIndex, target.inConnections.IndexOf(connection));
			return connection;
		}

		protected virtual void OnCreate(int sourceIndex, int targetIndex)
		{
		}

		public Status Execute()
		{
			return Execute(graphAgent, graphBlackboard);
		}

		public Status Execute(Component agent)
		{
			return Execute(agent, graphBlackboard);
		}

		public Status Execute(Component agent, Blackboard blackboard)
		{
			if (!isActive)
			{
				return Status.Resting;
			}
			connectionStatus = OnExecute(agent, blackboard);
			return connectionStatus;
		}

		protected virtual Status OnExecute(Component agent, Blackboard blackboard)
		{
			return targetNode.Execute(agent, blackboard);
		}

		public void ResetConnection()
		{
			ResetConnection(true);
		}

		public void ResetConnection(bool recursively)
		{
			if (connectionStatus != Status.Resting)
			{
				OnReset();
				connectionStatus = Status.Resting;
				if (recursively)
				{
					targetNode.ResetNode(recursively);
				}
			}
		}

		protected virtual void OnReset()
		{
		}
	}
}
